/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.systemui.qs.tiles;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.service.quicksettings.Tile;
import android.telecom.TelecomManager;
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Switch;

import com.android.ims.ImsManager;
import com.android.internal.telephony.TelephonyIntents;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.qs.tileimpl.QSTileImpl;

public class VolteTile extends QSTileImpl<BooleanState> {
    private static final String TAG = "VolteTile";
    public int QS_VOLTE = 415;
    private boolean mListening;
    private int mSlotId = 0;
    private ImsManager mImsManager ;
    private TelephonyManager mTelephonyManager;
    private final ContentObserver mObserver;

    public VolteTile(QSHost host, int soltId) {
        super(host);
        mSlotId = soltId;
        mImsManager = ImsManager.getInstance(mContext, mSlotId);
        mTelephonyManager = TelephonyManager.from(mContext);
        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        mObserver = new ContentObserver(new Handler()) {
            @Override
            public void onChange(boolean selfChange) {
                Log.d(TAG, "onChange");
                refreshState();
            }
        };
    }

    /* UNISOC: Modify for bug1335095 @{ */
    public void unregisterListen() {
        if (mTelephonyManager != null) {
            mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
        }
    }
    /* @} */

    @Override
    public BooleanState newTileState() {
        return new BooleanState();
    }

    @Override
    public void  handleSetListening(boolean listening) {
        super.handleSetListening(listening);
        if (mListening == listening) {
            return;
        }
        mListening = listening;
        if (listening) {
            final IntentFilter filter = new IntentFilter();
            filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
            filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
            mContext.registerReceiver(mReceiver, filter);
            int defaultDataSubId;
            if (isSupportDualLTE()) {
                defaultDataSubId = getSubId();
            } else {
                defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
            }
            mContext.getContentResolver().registerContentObserver(getNotifyContentUri(
                SubscriptionManager.ADVANCED_CALLING_ENABLED_CONTENT_URI, true, defaultDataSubId),
                true, mObserver);
        } else {
            mContext.unregisterReceiver(mReceiver);
            mContext.getContentResolver().unregisterContentObserver(mObserver);
        }
    }

    private static Uri getNotifyContentUri(Uri uri, boolean usingSubId, int subId) {
        return (usingSubId) ? Uri.withAppendedPath(uri, "" + subId) : uri;
    }

    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            if(state != TelephonyManager.CALL_STATE_OFFHOOK){
                refreshState();
            }
        };
    };

    @Override
    protected void handleClick() {
        if (getState().state == Tile.STATE_UNAVAILABLE) {
            return;
        }
        mImsManager.setEnhanced4gLteModeSetting(!mState.value);
    }

    private boolean isCurrentSimAvailable() {
        int currentSubId = getSubId();
        boolean isCurrentSimReady = mTelephonyManager.getSimState(mSlotId) ==
                TelephonyManager.SIM_STATE_READY;
        boolean isCurrentSimSubIdValid = SubscriptionManager.isValidSubscriptionId(currentSubId);
        Log.d(TAG, "mSlotId = " + mSlotId + " isDefaultDataSimReady = "
                + isCurrentSimReady + " isDefaultDataStandby = " + isCurrentSimSubIdValid);
        return isCurrentSimReady && isCurrentSimSubIdValid;
    }

    @Override
    protected void handleUpdateState(BooleanState state, Object arg) {
        if (mImsManager == null) {
            mImsManager = ImsManager.getInstance(mContext, mSlotId);
        }
        state.value = mImsManager.isEnhanced4gLteModeSettingEnabledByUser();
        state.label = getTileLabel();
        state.icon = ResourceIcon.get(R.drawable.ic_qs_volte_ex);
        if (isAirplaneModeOn() || !isCurrentSimAvailable() || isInCall()) {
            state.state = Tile.STATE_UNAVAILABLE;
            return;
        } else {
            if (mImsManager.isEnhanced4gLteModeSettingEnabledByUser()) {
                state.state = Tile.STATE_ACTIVE;
                state.contentDescription =  mContext.getString(
                        R.string.accessibility_quick_settings_volte_on);
            } else {
                state.state = Tile.STATE_INACTIVE;
                state.contentDescription =  mContext.getString(
                        R.string.accessibility_quick_settings_volte_off);
            }
        }
        state.expandedAccessibilityClassName = Switch.class.getName();
    }

    @Override
    public Intent getLongClickIntent() {
        // TODO Auto-generated method stub
        return getVolteSettingIntent();
    }

    @Override
    public int getMetricsCategory() {
        return QS_VOLTE;
    }

    @Override
    public CharSequence getTileLabel() {
        if (isSupportDualLTE()) {
            if (mSlotId == 0) {
                return mContext.getString(R.string.quick_settings_volte1_label);
            } else if (mSlotId == 1) {
                return mContext.getString(R.string.quick_settings_volte2_label);
            }
        }
        return mContext.getString(R.string.quick_settings_volte_label);
    }

    private boolean isAirplaneModeOn() {
        return Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())
                   || Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())) {
                refreshState();
            }
        }
    };

    private boolean isSupportDualLTE() {
        return QSFactoryImpl.isDeviceSupportDualLte();
    }

    private int getSubId() {
        int[] subIds = SubscriptionManager.getSubId(mSlotId);
        int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
        if (subIds != null && subIds.length >= 1) {
            subId = subIds[0];
        }
        return subId;
    }

    private Intent getVolteSettingIntent() {
        Intent intent = new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS);
        intent.putExtra(Settings.EXTRA_SUB_ID, getSubId());
        return intent;
    }

    private boolean isInCall() {
        return getTelecommManager().isInCall();
    }

    private TelecomManager getTelecommManager() {
        return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
    }
}
